#pragma once
#include <iostream>
#include <chrono>
#include <map>
#include <vector>
#include <string>
#include <functional>
namespace yansu::common{

class Timer{
public:
    struct TimerRecord{
        TimerRecord() = default;
        TimerRecord(const std::string &name , double time_used){
            func_name_ = name;
            add_time_used(time_used);
        }
        void add_time_used(double time_used){
            time_used_all_in_ms_.emplace_back(time_used);
        }
        std::string func_name_;
        std::vector<double> time_used_all_in_ms_;
    };
    template<typename F>
    static void Evaluate(F&& func, const std::string &name){
        auto t1 = std::chrono::steady_clock::now();
        std::forward<F>(func)();
        auto t2 = std::chrono::steady_clock::now();
        double time_used = std::chrono::duration_cast<std::chrono::duration<double>>(t2-t1).count() * 1000;
        if(records_.find(name)!=records_.end()){  //存在记录
            records_[name].add_time_used(time_used);
        }else{
            records_.insert({name,TimerRecord(name,time_used)});
        }
    }
    //格式化输出耗时信息
    static void PrintAllRecords(); 
    /// 写入文件，方便作图分析
    static void DumpIntoFile(const std::string& file_name);
    /// 获取某个函数的平均执行时间
    static double GetMeanTime(const std::string& func_name);
    /// 清理记录
    static void Clear() { records_.clear(); }

private:
    static std::map<std::string,TimerRecord> records_;
};

} // namespace yansu